home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_0399 / 381 / nlist.zoo / nlist.c next >
C/C++ Source or Header  |  1993-07-18  |  3KB  |  154 lines

  1. /* nlist for mintlib/toslib.
  2.  * Written by S.N. Henson and released into the public domain.
  3.  *
  4.  * Currently uses just standard and GST extended symbol formats.
  5.  */
  6.  
  7. #include <st-out.h>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. #include <errno.h>
  11. #include <macros.h>
  12. #include <nlist.h>
  13. #include <string.h>
  14.  
  15. #define SYM_BUFSIZE 100
  16. #define SYMSIZE sizeof(struct asym)
  17. #define GSYM_SIZE 23
  18.  
  19. static int sym_fd;
  20.  
  21. static long symcount;
  22.  
  23. static int getsym __PROTO((struct asym *sptr));
  24.  
  25. /* Read a symbol from a file and put it in sptr */
  26. static int getsym(sptr)
  27. struct asym *sptr;
  28. {
  29.     static struct asym symbuf[SYM_BUFSIZE],*symptr;
  30.     static long symread;
  31.     if( !symread )
  32.     {
  33.         symread=min(sizeof(symbuf),symcount);
  34.         if(symread!=read(sym_fd,symbuf,symread))
  35.         {
  36.             close(sym_fd);
  37.                         symread=0;
  38.             errno=EREAD; /* Premature EOF */
  39.             return -1;
  40.         }
  41.         symptr=symbuf;
  42.     }
  43.  
  44.     *sptr=*symptr++;
  45.     symread-=SYMSIZE;
  46.  
  47.         if( symread < 0 )
  48.         {
  49.                 symread=0;
  50.                 errno=EREAD;
  51.                 return -1;
  52.         }
  53.  
  54.     return 0;
  55. }
  56.  
  57. int nlist(file,nl)
  58. char *file;
  59. struct nlist *nl;
  60. {
  61.  
  62.     struct nlist *p;
  63.  
  64.     struct aexec hbuf;
  65.  
  66.     struct asym sym;
  67.  
  68.     long nl_count;
  69.  
  70.     if(!file || !nl)
  71.     {
  72.         errno=EFAULT;
  73.         return -1;
  74.     }
  75.  
  76.     if( ( sym_fd=open(file,O_RDONLY) ) == -1 ) return -1;            
  77.  
  78.     /* Read in file header */
  79.     read(sym_fd,&hbuf,sizeof(hbuf));
  80.  
  81.     /* Executable file ? */
  82.     if(A_BADMAG(hbuf)) 
  83.     {
  84.         close(sym_fd);
  85.         errno=ENOEXEC;
  86.         return -1;
  87.     }
  88.  
  89.     /* Any symbols? */
  90.     if( !(symcount=hbuf.a_syms) )
  91.     {
  92.         errno=EDOM;
  93.         return -1;
  94.     }
  95.  
  96.     if( symcount < sizeof(struct asym) )
  97.     {
  98.         close(sym_fd);
  99.         errno=EREAD;
  100.         return -1;
  101.     }
  102.  
  103.     /* Seek to symbol table */
  104.     if( A_SYMOFF(hbuf)!=lseek(sym_fd,A_SYMOFF(hbuf),SEEK_SET) )
  105.     {
  106.         close(sym_fd);
  107.         errno=EREAD;
  108.         return -1;
  109.     }
  110.  
  111.     /* Count number of symbols to match */
  112.     for(p=nl,nl_count=0;p->n_name;p++)
  113.     {
  114.         nl_count++;
  115.         p->n_value=p->n_type=0;
  116.     }
  117.  
  118.     if(!nl_count) return 0;
  119.  
  120.     do
  121.     {
  122.         char name[GSYM_SIZE];
  123.  
  124.         /* Get one symbol from file */
  125.         if(getsym(&sym)) return -1;
  126.  
  127.         symcount-=SYMSIZE;
  128.  
  129.         strncpy(name,sym.a_name,8);
  130.  
  131.         /* If extended symbol, get rest of name */
  132.         if( (sym.a_type & A_LNAM) == A_LNAM)
  133.         {
  134.             if( (symcount <= 0) || getsym((struct asym *)(name+8)))
  135.                                       return -1;
  136.             symcount-=SYMSIZE;
  137.             name[22]=0;
  138.         }
  139.         else name[8]=0;
  140.  
  141.         /* Check for match */
  142.         for(p=nl;p->n_name;p++)
  143.         {
  144.             if(p->n_type || strcmp(name,p->n_name)) continue;
  145.             p->n_value=sym.a_value;
  146.             p->n_type=sym.a_type;
  147.             if(--nl_count==0) return 0;
  148.         }
  149.     }
  150.     while(symcount > 0);
  151.  
  152.     return nl_count;
  153. }
  154.